#ifndef _HELPER_H
#define _HELPER_H

#include "Ogre.h"
//#include "OgreTextAreaOverlayElement.h"
//#include "OgreConfigFile.h"

#include "GameObjectManager.h"
#include "GameSceneManager.h"

using namespace Ogre;

//Stores the current state of the game (ie: on main menu, on battle mode, map editor)
class GameState
{
public:

	bool isGUIEnable;
	bool isShutdownRequested;
	bool SwitchMode;

	enum {
	SET_BATTLE_MODE = 1,
	SET_EDITOR_MODE = 2,
	SWITCH_MODE_ON = 3,
	SWITCH_MODE_OFF = 4,
	DISABLE_GUI = 5,
	ENABLE_GUI = 6,
	SHUTDOWN = 7

	};

	GameState() {
		isGUIEnable = true;
		isShutdownRequested = false;
		mGUIMode = SET_BATTLE_MODE;
		SwitchMode = false;
	}
	~GameState() {}
	
	bool isBattleMode()	{
		return (mGUIMode==SET_BATTLE_MODE) ? true : false;
	}
	bool isEditorMode()	{
		return (mGUIMode==SET_EDITOR_MODE) ? true : false;
	}

	void setGameState(unsigned short curState) {
		switch(curState)
		{
		case SET_BATTLE_MODE:
			mGUIMode = curState;
			break;
		case SET_EDITOR_MODE:
			mGUIMode = curState;
			break;
		case SHUTDOWN: 
			isShutdownRequested = true;
			break;
		case SWITCH_MODE_ON: //(curState==SWITCH_MODE_ON) ? true : false;
			SwitchMode = true;
			break;
		case SWITCH_MODE_OFF:
			SwitchMode = false;
			break;
		case ENABLE_GUI:
			isGUIEnable = true;
			break;
		case DISABLE_GUI:
			isGUIEnable = false;
			break;
		}
	}

private:
	
	

	//unsigned short mGUIstate;
	unsigned short mGUIMode;
};

class primitiveShapes
{
public :

	Ogre::String nombre_1;
	Ogre::String nombre_material;
	SceneNode* myManualObjectNode;

	primitiveShapes(Vector3 InitialPosition, Vector3 DestinationPosition)
	{
		SceneManager *mSceneMgr = GameSceneManager::getSingleton()->getSceneManager();

		Ogre::String name = "mo" + StringConverter::toString(GameObjectManager::getSingleton()->getNextCompIndex());

		ManualObject* myManualObject =  mSceneMgr->createManualObject(name); 
		
		//nombre_1 = name + "1";

		name = "node" + StringConverter::toString(GameObjectManager::getSingleton()->getNextCompIndex());

		myManualObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(name); 
		
		name = "material" + StringConverter::toString(GameObjectManager::getSingleton()->getNextCompIndex());

		MaterialPtr myManualObjectMaterial = MaterialManager::getSingleton().create(name,"debugger"); 
		
		//nombre_material = name + "material";

		myManualObjectMaterial->setReceiveShadows(false); 
		myManualObjectMaterial->getTechnique(0)->setLightingEnabled(true); 
		myManualObjectMaterial->getTechnique(0)->getPass(0)->setDiffuse(0,0,1,0); 
		myManualObjectMaterial->getTechnique(0)->getPass(0)->setAmbient(0,0,1); 
		myManualObjectMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(0,0,1); 
		
		myManualObject->begin(name+"material", Ogre::RenderOperation::OT_LINE_LIST); 
		myManualObject->position(InitialPosition); 
		myManualObject->position(DestinationPosition); 
		// etc 
		myManualObject->end(); 
		 
		myManualObjectNode->attachObject(myManualObject);
   }
	void setPos(Vector3 InitialPosition, Vector3 DestinationPosition,SceneManager *mSceneMgr)
	{
		ManualObject* myManualObject =  mSceneMgr->getManualObject(nombre_1); 
		//MaterialPtr myManualObjectMaterial = MaterialManager::getSingleton().getByName(nombre);
		myManualObject->begin(nombre_material, Ogre::RenderOperation::OT_LINE_LIST); 
		myManualObject->position(InitialPosition); 
		myManualObject->position(DestinationPosition); 
		//myManualObjectNode->setPosition(
		myManualObject->end(); 
	}

};

/*
namespace HeightFunction
{

	class MyRaySceneQueryListener: public RaySceneQueryListener
	{
	public:
		inline bool queryResult(SceneQuery::WorldFragment *fragment, Real distance)
		{
			resultDistance = distance;
			return false;
		}
		inline bool queryResult(MovableObject *obj, Real distance)
		{
			resultDistance = distance;
			return false;
		}

		float resultDistance;
	};

	bool initialized = false;
	RaySceneQuery* raySceneQuery;
	Ray updateRay;
	MyRaySceneQueryListener *raySceneQueryListener;

	//Initializes the height function. Call this before calling getTerrainHeight()
	void initialize(SceneManager *sceneMgr){
		if (!initialized){
			initialized = true;
			updateRay.setOrigin(Vector3::ZERO);
			updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
			raySceneQuery = sceneMgr->createRayQuery(updateRay);
			raySceneQuery->setQueryTypeMask(Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK);   
			raySceneQuery->setWorldFragmentType(Ogre::SceneQuery::WFT_SINGLE_INTERSECTION); 
			raySceneQueryListener = new MyRaySceneQueryListener;
		}
	}

	//Gets the height of the terrain at the specified x/z coordinate
	//The userData parameter isn't used in this implementation of a height function, since
	//there's no need for extra data other than the x/z coordinates.
	inline float getTerrainHeight(const float x, const float z, void *userData = NULL){
		updateRay.setOrigin(Vector3(x, 0.0f, z));
		updateRay.setDirection(Vector3::UNIT_Y);
		raySceneQuery->setRay(updateRay);
		raySceneQuery->execute(raySceneQueryListener);

		return raySceneQueryListener->resultDistance;
	}
}
*/

/*
class OgreText
{
public:

	OgreText(Ogre::String szElement) //char *szElement
	{

   }
   ~OgreText()
   {

   }
   void showTextNormal(Ogre::String szString,int x,int y) //char *szString //char *szString
   {

   }
 
private:

};
*/

#endif